﻿// 麻省理工学院许可证
//
// 版权所有 (c) 2023-2025 缄默 联系电话/18521355630 
//
// 特此免费授予获得本软件的任何人以处理本软件的权利，但须遵守以下条件：在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
//
// 软件按“原样”提供，不提供任何形式的明示或暗示的保证，包括但不限于对适销性、适用性和非侵权的保证。
// 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他责任负责，无论是因合同、侵权或其他方式引起的，与软件或其使用或其他交易有关。

using System.Diagnostics;

namespace LvcChong
{
    public class NLogHelper
    {
        private static string _curAssName = string.Empty;

        private static NLog.ILogger Logger => NLog.LogManager.GetLogger(GetClassName());

        private static List<string> _ignoreClasses = new List<string>();

        public static void SetClassNameIgnore(params string[] clz)
        {
            if (clz == null!) return;
            _ignoreClasses.Clear();
            foreach (var item in clz)
            {
                _ignoreClasses.Add(item);
            }
        }

        private static string CurrFullClassName()
        {
            if (!string.IsNullOrWhiteSpace(_curAssName)) return _curAssName;

            _curAssName = typeof(NLogHelper).FullName!;
            return _curAssName;
        }

        /// <summary>
        /// 获取距离调用日志最近的类名
        /// </summary>
        /// <returns></returns>
        private static string GetClassName()
        {
            var curAssName = $"{typeof(NLogHelper).FullName}.GetClassName";
            try
            {
                var st = new StackTrace();

                for (int i = 0; i < st.FrameCount; i++)
                {
                    var method = st.GetFrame(i)!.GetMethod();
                    if (method!.DeclaringType != null && !method.DeclaringType.FullName!.Equals(CurrFullClassName()) // 不是当前类
                        && !_ignoreClasses.Any(x => System.Text.RegularExpressions.Regex.IsMatch(method.DeclaringType.FullName, x))
                        && method.DeclaringType?.Name?.Contains("<>") == false // 不是匿名方法
                        )
                    {
                        return $"{method.DeclaringType.FullName}.{method.Name}";
                    }
                }
            }
            catch { }

            return curAssName;
        }

        public static void Trace(object value) => Logger.Trace(value);

        public static void Trace(string message, object argument) => Logger.Trace(message, argument);

        public static void Trace<T>(T value) => Logger.Trace(value);

        public static void Trace(Exception exception, string message) => Logger.Trace(exception, message);

        public static void Trace(Exception exception, string message, params object[] args) => Logger.Trace(exception, message, args);

        public static void Trace(string message) => Logger.Trace(message);

        public static void Trace(string message, params object[] args) => Logger.Trace(message, args);

        public static void Debug(object value) => Logger.Debug(value);

        public static void Debug(string message, object argument) => Logger.Debug(message, argument);

        public static void Debug<T>(T value) => Logger.Debug(value);

        public static void Debug(Exception exception, string message) => Logger.Debug(exception, message);

        public static void Debug(Exception exception, string message, params object[] args) => Logger.Debug(exception, message, args);

        public static void Debug(string message) => Logger.Debug(message);

        public static void Debug(string message, params object[] args) => Logger.Debug(message, args);

        public static void Info(object value) => Logger.Info(value);

        public static void Info(string message, object argument) => Logger.Info(message, argument);

        public static void Info<T>(T value) => Logger.Info(value);

        public static void Info(Exception exception, string message) => Logger.Info(exception, message);

        public static void Info(Exception exception, string message, params object[] args) => Logger.Info(exception, message, args);

        public static void Info(string message) => Logger.Info(message);

        public static void Info(string message, params object[] args) => Logger.Info(message, args);

        public static void Warn(object value) => Logger.Warn(value);

        public static void Warn(string message, object argument) => Logger.Warn(message, argument);

        public static void Warn<T>(T value) => Logger.Warn(value);

        public static void Warn(Exception exception, string message) => Logger.Warn(exception, message);

        public static void Warn(Exception exception, string message, params object[] args) => Logger.Warn(exception, message, args);

        public static void Warn(string message) => Logger.Warn(message);

        public static void Warn(string message, params object[] args) => Logger.Warn(message, args);

        public static void Error(object value) => Logger.Error(value);

        public static void Error(string message, object argument) => Logger.Error(message, argument);

        public static void Error<T>(T value) => Logger.Error(value);

        public static void Error(Exception exception, string message) => Logger.Error(exception, message);

        public static void Error(Exception exception, string message, params object[] args) => Logger.Error(exception, message, args);

        public static void Error(string message) => Logger.Error(message);

        public static void Error(string message, params object[] args) => Logger.Error(message, args);

        public static void Fatal(object value) => Logger.Fatal(value);

        public static void Fatal(string message, object argument) => Logger.Fatal(message, argument);

        public static void Fatal<T>(T value) => Logger.Fatal(value);

        public static void Fatal(Exception exception, string message) => Logger.Fatal(exception, message);

        public static void Fatal(Exception exception, string message, params object[] args) => Logger.Fatal(exception, message, args);

        public static void Fatal(string message) => Logger.Fatal(message);

        public static void Fatal(string message, params object[] args) => Logger.Fatal(message, args);
    }
}